#include <iostream>
#include "xtp_modle_api.h"
#include "xtp_trader_resp.h"

using namespace std;

XTP::API::TraderApi* global_trader_api_obj = NULL;
callback_interface* global_callback_interface = NULL;

#ifdef WIN32
	#ifdef MYDLL_EXPORTS
		#define MYDLLAPI  extern "C" __declspec(dllexport)
	#else
		#define MYDLLAPI  extern "C" __declspec(dllimport)
	#endif
#else
	#define MYDLLAPI extern "C"
#endif

///创建交易接口对象;
MYDLLAPI int create_trader_api(int client_id, char* save_file_path) {
    global_trader_api_obj = XTP::API::TraderApi::CreateTraderApi(client_id, save_file_path);
    if (global_trader_api_obj == NULL) {
        cout<<"create quote api failed ..."<<endl;
        return -1;
    }
    cout<<"create quote api success ..."<<endl;
    return 0;
}

///释放交易接口对象;
MYDLLAPI void release_trader_api(){
    if (global_trader_api_obj == NULL) {
        return;
    }
    global_trader_api_obj->Release();
}

///绑定用户自定义的应答接口
MYDLLAPI int reg_response_cb(callback_interface* _cb_interface){
    global_callback_interface = _cb_interface;
    return 1;
}

///登陆
MYDLLAPI int login(char* ip, int port, char* user, char* password){
     if (global_trader_api_obj == NULL) {
        cout<<"create quote api failed ..."<<endl;
        return -1;
    }
    CXTP_Trader_Resp* trader_resp = new CXTP_Trader_Resp();
    trader_resp->m_resp_interface = global_callback_interface;
    global_trader_api_obj->RegisterSpi(trader_resp);
    int session_id = global_trader_api_obj->Login(ip, port, user, password, XTP_PROTOCOL_TYPE::XTP_PROTOCOL_TCP); //登录交易服务器
     if (session_id == 0) {
       XTPRI* xtp_pri = global_trader_api_obj->GetApiLastError();
       if (xtp_pri != NULL) {
           cout<<"login error, id:"<<xtp_pri->error_id<<" msg:"<<string(xtp_pri->error_msg).c_str()<<endl;
       }
       return -1;
    }
	return session_id;
}

///登出
MYDLLAPI void logout(int session_id){
    if (global_trader_api_obj != NULL) {
        global_trader_api_obj->Logout(session_id);
     }
}

///获取当前交易日
MYDLLAPI const char* get_trading_day(){
     if (global_trader_api_obj != NULL) {
           const char* tDay= global_trader_api_obj->GetTradingDay();
           return tDay;
     }
     return NULL;
}

///订阅公共流
MYDLLAPI void subscribe_public_topic(int resume_type){
    if (global_trader_api_obj != NULL) {
        global_trader_api_obj->SubscribePublicTopic((XTP_TE_RESUME_TYPE)resume_type);
    }
}

///设置软件开发版本号
MYDLLAPI void set_software_version(char* version){
     if (global_trader_api_obj != NULL) {
        global_trader_api_obj->SetSoftwareVersion(version);
     }
}

///设置软件开发key
MYDLLAPI  void set_software_key(char* key){
    if (global_trader_api_obj != NULL) {
        global_trader_api_obj->SetSoftwareKey(key);//设定用户的开发代码，在XTP申请开户时，由xtp人员提供
    }
}

///设置心跳检测时间间隔，单位为秒
MYDLLAPI void set_heartbeat_interval(long long unsigned int interval){
    if (global_trader_api_obj != NULL) {
        global_trader_api_obj->SetHeartBeatInterval(interval);
    }
}

///报单录入请求
MYDLLAPI long long unsigned int insert_order(PXTPOrderInsertInfo *order, long long unsigned int session_id){
    if (global_trader_api_obj == NULL) {
        cout<<"create quote api failed ..."<<endl;
        return -1;
    }
    uint64_t ret = global_trader_api_obj->InsertOrder(order, session_id);
    if (ret == 0) {
       XTPRI* xtp_pri = global_trader_api_obj->GetApiLastError();
       if (xtp_pri != NULL) {
           cout<<"insert order error, id:"<<xtp_pri->error_id<<" msg:"<<string(xtp_pri->error_msg).c_str()<<endl;
       }
       return -1;
    }
    return (long long unsigned int)ret;
}

///报单操作请求
MYDLLAPI long long unsigned int cancel_order(long long unsigned int order_xtp_id, long long unsigned int session_id){
    if (global_trader_api_obj == NULL) {
        cout<<"create quote api failed ..."<<endl;
        return -1;
    }
    uint64_t ret = global_trader_api_obj->CancelOrder(order_xtp_id, session_id);
    if (ret == 0) {
       XTPRI* xtp_pri = global_trader_api_obj->GetApiLastError();
       if (xtp_pri != NULL) {
           cout<<"cancel order error, id:"<<xtp_pri->error_id<<" msg:"<<string(xtp_pri->error_msg).c_str()<<endl;
       }
       return -1;
    }
    return (long long unsigned int)ret;
}

///根据报单ID请求查询报单
MYDLLAPI int query_order_by_xtpid(long long unsigned int order_xtp_id, long long unsigned int session_id, int request_id){
    if (global_trader_api_obj == NULL) {
        cout<<"create quote api failed failed ..."<<endl;
        return -1;
    }
    uint64_t ret = global_trader_api_obj->QueryOrderByXTPID(order_xtp_id, session_id, request_id);
    if (ret == 0) {
       XTPRI* xtp_pri = global_trader_api_obj->GetApiLastError();
       if (xtp_pri != NULL) {
           cout<<"query order by xtpid error, id:"<<xtp_pri->error_id<<" msg:"<<string(xtp_pri->error_msg).c_str()<<endl;
       }
       return -1;
    }
    return (long long unsigned int)ret;
}

///请求查询报单
MYDLLAPI int query_orders(PXTPQueryOrderReq *query_param, long long unsigned int session_id, int request_id){
     if (global_trader_api_obj == NULL) {
        cout<<"create quote api failed ..."<<endl;
        return -1;
    }
    uint64_t ret = global_trader_api_obj->QueryOrders(query_param, session_id, request_id);
    if (ret == 0) {
       XTPRI* xtp_pri = global_trader_api_obj->GetApiLastError();
       if (xtp_pri != NULL) {
           cout<<"query orders error, id:"<<xtp_pri->error_id<<" msg:"<<string(xtp_pri->error_msg).c_str()<<endl;
       }
       return -1;
    }
    return (long long unsigned int)ret;
}

///根据委托编号请求查询相关成交
MYDLLAPI int query_trades_by_xtpid (long long unsigned int order_xtp_id, long long unsigned int session_id, int request_id){
     if (global_trader_api_obj == NULL) {
        cout<<"create quote api failed ..."<<endl;
        return -1;
    }
    uint64_t ret = global_trader_api_obj->QueryTradesByXTPID(order_xtp_id, session_id, request_id);
    if (ret == 0) {
       XTPRI* xtp_pri = global_trader_api_obj->GetApiLastError();
       if (xtp_pri != NULL) {
           cout<<"query trades by xtpid error, id:"<<xtp_pri->error_id<<" msg:"<<string(xtp_pri->error_msg).c_str()<<endl;
       }
       return -1;
    }
    return (long long unsigned int)ret;
}

///请求查询已成交
MYDLLAPI int query_trades(PXTPQueryTraderReq *query_param, long long unsigned int session_id, int request_id){
     if (global_trader_api_obj == NULL) {
        cout<<"create quote api failed ..."<<endl;
        return -1;
    }
    uint64_t ret = global_trader_api_obj->QueryTrades(query_param, session_id, request_id);
    if (ret == 0) {
       XTPRI* xtp_pri = global_trader_api_obj->GetApiLastError();
       if (xtp_pri != NULL) {
           cout<<"query trades error, id:"<<xtp_pri->error_id<<" msg:"<<string(xtp_pri->error_msg).c_str()<<endl;
       }
       return -1;
    }
    return (long long unsigned int)ret;
}

///请求查询投资者持仓
MYDLLAPI int query_position(char *ticker, long long unsigned int session_id, int request_id){
     if (global_trader_api_obj == NULL) {
        cout<<"create quote api failed ..."<<endl;
        return -1;
    }
    uint64_t ret = global_trader_api_obj->QueryPosition(ticker, session_id, request_id);
    if (ret == 0) {
       XTPRI* xtp_pri = global_trader_api_obj->GetApiLastError();
       if (xtp_pri != NULL) {
           cout<<"query position error, id:"<<xtp_pri->error_id<<" msg:"<<string(xtp_pri->error_msg).c_str()<<endl;
       }
       return -1;
    }
    return (long long unsigned int)ret;
}

///请求查询资产
MYDLLAPI int query_asset(long long unsigned int session_id, int request_id){
     if (global_trader_api_obj == NULL) {
        cout<<"create quote api failed ..."<<endl;
        return -1;
    }
    uint64_t ret = global_trader_api_obj->QueryAsset(session_id, request_id);
    if (ret == 0) {
       XTPRI* xtp_pri = global_trader_api_obj->GetApiLastError();
       if (xtp_pri != NULL) {
           cout<<"query asset error, id:"<<xtp_pri->error_id<<" msg:"<<string(xtp_pri->error_msg).c_str()<<endl;
       }
       return -1;
    }
    return (long long unsigned int)ret;
}
